home *** CD-ROM | disk | FTP | other *** search
- /*
- File: CLUTBuilder.c
-
- Contains: this file contains functions used to pull colors from a PICT. You activate it by
- calling CollectColors(PicHandle) with PicHandle set to a PICT that you have already
- loaded into memory. It will almost invariably return a (handle to a) color table
- (that contains at least black and white) however the color table is not at all clean
- in the current implementation. It is probably ok if you run it through NewPalette.
- If it runs across a direct pixmap it won't bomb but it won't add any colors to the
- color table.
-
- WARNING: This code has been tested but it has not been tested thoroughly;
- USE AT YOUR OWN RISK!
-
- Written by: Jon Zap
-
- Copyright: Copyright © 1989-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/8/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
- #include "CLUTBuilder.h"
- #define applec
-
-
- /* Add a color to the color table. */
- void AddRGBColor(RGBColor * rgb)
- {
- long numSpecs,sizeInBytes;
- int i,ctSize;
- CTabPtr TablePtr;
- RGBColor rgbx;
-
- if (gColorError)
- return;
-
- TablePtr = (*gColorTable);
- ctSize = TablePtr -> ctSize;
- for (i = 0; i <= ctSize; i++) {
- rgbx = TablePtr->ctTable[i].rgb;
- if (rgbx.red==(*rgb).red &&
- rgbx.green==(*rgb).green &&
- rgbx.blue==(*rgb).blue)
- return; /* if already there, done */
- }
- numSpecs = (long) (++(**gColorTable).ctSize); /* add a colorspec to table */
- sizeInBytes = (numSpecs * sizeof(ColorSpec)) + sizeof(ColorTable);
- SetHandleSize((Handle)gColorTable, sizeInBytes);
- if ((gColorError = MemError()) == noErr) {
- (**gColorTable).ctTable[numSpecs].rgb = *rgb;
- (**gColorTable).ctTable[numSpecs].value = 0;
- }
- }
-
- /* Add the contents of another color table to our color table.*/
- void AddColorTable(CTabHandle cTab)
- {
- short index,size;
- RGBColor color;
- size = (**cTab).ctSize;
- for (index= 0; index <= size; index++) {
- color = (**cTab).ctTable[index].rgb;
- AddRGBColor(&color);
- }
- }
-
- /* Add the foreground color of the current port to the color table. */
- void AddRGBForeColor()
- {
- #ifdef applec
- AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbFgColor));
- #else
- AddRGBColor(&((*(CGrafPtr)thePort).rgbFgColor));
- #endif
- }
-
- /* Add the background color of the current port to the color table. */
- void AddRGBBackColor()
- {
- #ifdef applec
- AddRGBColor(&((*(CGrafPtr)qd.thePort).rgbBkColor));
- #else
- AddRGBColor(&((*(CGrafPtr)thePort).rgbBkColor));
- #endif
- }
-
- /* Add colors from a PixPat to a color table. */
- void AddPixPat(PixPatHandle pPat)
- {
- switch ((**pPat).patType) {
-
- case 0: /* one-bit patterns are drawn in the foreground and background color. */
- AddRGBForeColor();
- AddRGBBackColor();
- break;
- case 1: /* Type 1 PixPats have a color table. */
- AddColorTable((**(**pPat).patMap).pmTable);
- break;
- }
- }
-
- /* Add colors from the pen PixPat to the color table. */
- void AddPenPixPat()
- {
- #ifdef applec
- AddPixPat((*(CGrafPtr)qd.thePort).pnPixPat);
- #else
- AddPixPat((*(CGrafPtr)thePort).pnPixPat);
- #endif
- }
-
- /* Add colors from the fill PixPat to the color table. */
- void AddFillPixPat()
- {
- #ifdef applec
- AddPixPat((*(CGrafPtr)qd.thePort).fillPixPat);
- #else
- AddPixPat((*(CGrafPtr)thePort).fillPixPat);
- #endif
- }
-
- /* Add colors because we are about to draw an object. */
- void AddVerb(GrafVerb verb)
- {
- switch (verb) {
-
- case kQDGrafVerbFrame:
- case kQDGrafVerbPaint: /* Framed and painted objects are drawn in the pen PixPat. */
- AddPenPixPat();
- break;
- case kQDGrafVerbErase: /* Erased objects are drawn in the background color. */
- AddRGBBackColor();
- break;
- case kQDGrafVerbFill:
- /* Filled objects are drawn in the fill PixPat. The fillPixPat is
- a pattern used to record fill commands for pictures. First, a
- command to set the fillPixPat is recorded, then the fill command
- is recorded. */
- AddFillPixPat();
- }
- }
-
- /* bottleneck routines follow . . . */
-
- pascal void ColorTextProc(short byteCount, Ptr textBuf, Point numer, Point denom)
- { /* Text is drawn with the foreground and background colors.*/
- #ifdef applec
- #pragma unused (byteCount, textBuf, numer, denom)
- #endif
- AddRGBForeColor();
- AddRGBBackColor();
- }
-
- pascal void ColorLineProc(Point newPt)
- { /* Lines are drawn with the pen PixPat. */
- #ifdef applec
- #pragma unused (newPt)
- #endif
- AddPenPixPat();
- }
-
- pascal void ColorRectProc(GrafVerb verb,Rect* r)
- {
- #ifdef applec
- #pragma unused (r)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorRRectProc(GrafVerb verb,Rect* r, short ovalWidth,short ovalHeight)
- {
- #ifdef applec
- #pragma unused (r, ovalWidth, ovalHeight)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorOvalProc(GrafVerb verb,Rect r)
- {
- #ifdef applec
- #pragma unused (r)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorArcProc(GrafVerb verb,Rect* r,short startAngle,short arcAngle)
- {
- #ifdef applec
- #pragma unused (r, startAngle, arcAngle)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorPolyProc(GrafVerb verb, PolyHandle poly)
- {
- #ifdef applec
- #pragma unused (poly)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorRgnProc(GrafVerb verb,RgnHandle rgn)
- {
- #ifdef applec
- #pragma unused (rgn)
- #endif
- AddVerb(verb);
- }
-
- pascal void ColorBitsProc(BitMap* BitsPtr,Rect srcRect, Rect dstRect,short mode,RgnHandle maskRgn)
- {
- #ifdef applec
- #pragma unused (srcRect, dstRect, mode, maskRgn)
- #endif
- PixMapPtr aPixMap;
- short tempRB;
-
- /* Get the PixMap that we are about to draw. SrcBits might be a BitMap, or
- one of two different kinds of PixMap pointers. */
- tempRB = BitsPtr->rowBytes; /* local copy of rowBytes */
- if (tempRB < 0) { /* high bit set? */
- if ((tempRB<<1) < 0) /* next to high bit set? */
- aPixMap = (PixMapPtr)BitsPtr; /* ptr to PixMap handle */
- else
- aPixMap = (PixMapPtr) BitsPtr; /* pointer to a PixMap */
- if ((*aPixMap).pixelSize > maxPixDepth) /* deepest pixmap so far? */
- maxPixDepth = (*aPixMap).pixelSize;
- if ((*aPixMap).pixelType==16) {
- foundDirect = true;
- return; /* direct pixmap? eek! */
- }
- AddColorTable((*aPixMap).pmTable); /* it has its own color table. */
- }
- else {
- /* It's just a BitMap; it will use the background and foreground colors. */
- AddRGBBackColor();
- AddRGBForeColor();
- }
- }
-
- RGBColor whiteRGB = { 0xFFFF,0xFFFF,0xFFFF };
- RGBColor blackRGB = { 0,0,0 };
-
- CTabHandle CollectColors(PicHandle fromPicture,short * depthPtr,short * directFlagPtr)
- {
- CTabHandle colors;
- CQDProcs bottlenecks;
-
- /* Set the bottlenecks. These bottlenecks will figure out what colors are in
- a picture, but won't draw anything.
- Note: the bottlenecks are installed in thePort, which must be a color port.
- */
- SetStdCProcs(&bottlenecks);
- bottlenecks.textProc = NewQDTextProc(ColorTextProc);
- bottlenecks.lineProc = NewQDLineProc(ColorLineProc);
- bottlenecks.rectProc = NewQDRectProc(ColorRectProc);
- bottlenecks.rRectProc = NewQDRRectProc(ColorRRectProc);
- bottlenecks.ovalProc = NewQDOvalProc(ColorOvalProc);
- bottlenecks.arcProc = NewQDArcProc(ColorArcProc);
- bottlenecks.polyProc = NewQDPolyProc(ColorPolyProc);
- bottlenecks.rgnProc = NewQDRgnProc(ColorRgnProc);
- bottlenecks.bitsProc =NewQDBitsProc(ColorBitsProc);
-
- /* Create a color table containing black and white. */
- foundDirect = false; /* haven't found a direct pixmap yet */
- maxPixDepth = 1; /* assume we will find a bitmap */
- colors = (CTabHandle) NewHandle( sizeof(ColorTable) + sizeof(ColorSpec) );
- if (colors) {
- (**colors).ctSize = 1; /* 2 entries */
- #ifdef applec
- (**colors).ctFlags = 0x8000;
- #else
- (**colors).transIndex = 0x8000;
- #endif
- (**colors).ctSeed = GetCTSeed();
- (**colors).ctTable[0].rgb = whiteRGB; /*first entry is white*/
- (**colors).ctTable[1].rgb = blackRGB; /*second entry is black*/
- /* Now play back the picture to get the colors. The dstRect doesn't
- matter since our bottlenecks will never actually draw. We use global
- variables (gColorError and gColorTable) to communicate with the
- bottlenecks. */
- #ifdef applec
- (*(qd.thePort)).grafProcs = (QDProcs *) &bottlenecks;
- #else
- (*thePort).grafProcs = (QDProcs *) &bottlenecks;
- #endif
- gColorError = noErr;
- gColorTable = colors;
- DrawPicture(fromPicture, &((**fromPicture).picFrame));
- #ifdef applec
- (*(qd.thePort)).grafProcs = 0L;
- #else
- (*thePort).grafProcs = 0L;
- #endif
- *depthPtr = maxPixDepth;
- *directFlagPtr = foundDirect;
-
- /* Fail if error occurred while within the color bottlenecks. */
- if (gColorError != noErr) {
- DisposeHandle((Handle)colors);
- colors = 0L;
- }
- }
- return colors;
- }
-